JAVA | equals 的正确姿势

职员(Employee)及其子类(Manager),当判断对象是否等同取决于所有属性时,建议使用

1
if (getClass() != otherObject.getClass()) return false;

而不是

1
if (!(otherObject instanceof Employee)) return false;

如果当父类能够明确判断对象是否相同的条件时,可以使用instanceof。比如,实际中职员都有一个唯一ID,只要id相同即是同一个职员。那么将父类Employee的equals方法设计为判断ID值是否相同即可,当然hashCode方法也要由id来决定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public int hashCode() {
return Objects.hash(this.id);
}
@Override
public boolean equals(Object otherObject) {
if (this == otherObject) return true;
if (otherObject == null) return false;
if (!(otherObject instanceof Employee)) return false;
Employee other = (Employee) otherObject;
return this.id == other.id;
}

全部代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class Employee {
private String name;
private double salary;
private LocalDate hireDay;
public Employee(String name, double salary, int year, int month, int day) {
this.name = name;
this.salary = salary;
this.hireDay = LocalDate.of(year, month, day);
}
public String getName() {
return this.name;
}
public double getSalary() {
return this.salary;
}
public LocalDate getHireDay() {
return this.hireDay;
}
public void raiseSalary(double byPercent) {
double raise = this.salary * byPercent / 100;
this.salary += raise;
}
@Override
public int hashCode() {
return Objects.hash(this.name, this.salary, this.hireDay);
}
@Override
public boolean equals(Object otherObject) {
if (this == otherObject) return true;
if (otherObject == null) return false;
if (getClass() != otherObject.getClass()) return false;
Employee other = (Employee) otherObject;
return Objects.equals(this.name, other.name) && this.salary == other.salary
&& Objects.equals(this.hireDay, other.hireDay);
}
@Override
public String toString() {
return getClass().getName() + " [name=" + name + ", salary=" + salary
+ ", hireDay=" + hireDay + "]";
}
}
class Manager extends Employee {
private double bonus;
public Manager(String name, double salary, int year, int month, int day) {
super(name, salary, year, month, day);
bonus = 0;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
public double getSalary() {
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
@Override
public int hashCode() {
return super.hashCode() + 17 * Double.hashCode(bonus);
}
@Override
public boolean equals(Object otherObject) {
if (!super.equals(otherObject)) return false;
Manager other = (Manager) otherObject;
return bonus == other.bonus;
}
}